electronic.alchemy :: Multiple Models
electronic.alchemy
where the past meets the future
pike > Fins > Developer > Multiple Models

Multiple Models

Created by hww3. Last updated by hww3, 15 years ago. Version #4.

Most Fins applications take advantage of the Model framework in order to provide easier access to data located in SQL databases. Usually this data is stored in a single database, however some applications will have a need to access data located in multiple databases, perhaps spread across different database provider types (such as Postgress or MySQL).

In order to make it easier to access multiple datasources from a single application, Fins allows multiple model definitions to be included in the application's configuration file.

For example, perhaps we have the following (default) data model defined in our application:

[model]
# the id field is optional
id=my_default_model
class=model
datasource=sqlite:///tmp/db.sqlite3

We can access this model's context in any of the following ways:

// the default model, as defined in the [model] section is always
// available by requesting the _default model datasource.
Fins.Model.DataModelContext c = Fins.DataSource._default;

or

// if we have defined the id field in a model's definition, we can use
// that handle to get a context as well.
Fins.Model.DataModelContext c = Fins.DataSource.my_default_model;

or

// finally, Fins.Model provides a helper method that returns the default 
// model context object.
Fins.Model.DataModelContext c = Fins.Model.get_default_context();

or

// if we just need to do some find operations, there's a shortcut to the default
// context's find helper in the Model module.
array users = Fins.Model.find.users_all();

Now, perhaps we need to access data from a different database. To do this, we add an additional model definition to our application's configuration file. In order to prevent two configuration sections from having the same name, we use the following convention to label these additional model definition sections: [model_defid] where defid is a unique identifier we'll use to identifer this model.

In the following example, we've defined a model that will hold our user objects, and we'll give this definition the id of "ext_users".

[model_ext_users]
id=ext_users
datasource=sqlite:///tmp/db2.sqlite3
definition_module=ExtUsers

In this example, we're using the 3 attributes which are mandatory when defining additional data models:

It's possible to control sql level debugging for each model definition by using the debug attribute. Simply include this attribute with a value of "1" for the definitions you wish to enable sql logging for.

Note that our additional definitions don't have a class attribute. That's because the class attribute is used by the application loader to specify the class that will "spin up" the Fins model system. The default implementation used by applications out of the box, Fins.FinsModel, includes support for multiple models.

When a Fins application starts up, model's "master object", which defined by the class attribute in your app's [model] config section handles setup of everything model related in your app. By default, it sets up the default model defined in [model]. Once the default model is configured, it looks for other configuration sections whose name is like [model_defid], where defid is a unique string used to identify that additional model. Configuration is handled exactly as the default definition, and the resulting DataModelContext is stored in a mapping in Fins.Model. These contexts can be retrieved by using Fins.DataSources.defid or Fins.Model.get_context(defid).

For example:

Fins.Model.DataModelContext c;

c = Fins.DataSource.ext_users; // or c = Fins.Model.get_context("ext_users");

The Fins model builder tool (pike -x fins model) includes support for auto-configuring additional model definitions. Use the --model argument to specify the model definition you want to work with (assuming it's already been added to the app's config file).

You'll need to ensure that the base definition module has been created before invoking the model configuration tool, otherwise you'll get an error.

In the above example, that means we'd create the following directories in our app dir before running the model builder utility:

modules/ExtUsers.pmod/DataMappings.pmod
modules/ExtUsers.pmod/Objects.pmod

Then:

pike -x fins start model MyAppName --model=ext_users scan

Not categorized | RSS Feed | BackLinks

comments powered by Disqus